package peer.model.transfer.runnable;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;

import model.dto.FileDTO;
import model.dto.UserDTO;
import model.enums.UserStatusType;
import peer.model.consts.ConnectionsConsts;
import peer.model.consts.TransferConsts;


public class FileDownloadInstance implements Runnable {

	Map<UserDTO, Socket> peersMap;
	private FileDTO requestedFile;

	private FileOutputStream fileBuilt;
	private ArrayList<UserDTO> peers;

	public FileDownloadInstance(ArrayList<UserDTO> peers, FileDTO requestedFile){
		this.requestedFile=requestedFile;
		this.peersMap=createPeersConnections(peers);//create all connections with peers
		this.peers=peers;
	}


	private Map<UserDTO, Socket> createPeersConnections(ArrayList<UserDTO> peersArray){
		Map<UserDTO, Socket> connections=new HashMap<UserDTO, Socket>();

		for(UserDTO peer : peersArray){
			try{
				System.out.println("attemping connection with " + peer.getIp() + ":" + ConnectionsConsts.PEER_REQUEST_LISTENING_PORT);
				Socket attempCnx=new Socket(peer.getIp(), ConnectionsConsts.PEER_REQUEST_LISTENING_PORT);
				if(attempCnx.isConnected()){
					peer.setStatus(UserStatusType.READY);
					connections.put(peer, attempCnx);
				}
			}catch(IOException e){
				e.printStackTrace(System.err);
			}
		}
		return connections;
	}

	@Override
	public void run() {
		int blockCount= 2;//requestedFile.getSize()/TransferConsts.PARTITION_SIZE;
		int blocksLeft=blockCount;

		int currentBlock=0;
		System.out.println(blocksLeft + " blocks to download");
		ArrayList<Thread> currentDownloads=new ArrayList<Thread>();
		int var=0;
		while(blocksLeft>0){
			System.out.println("new block thread");
			Thread newThread=new Thread(new BlockDownloadInstance(this.requestedFile, currentBlock++, this.peersMap.get(this.peers.get(var++)), this.fileBuilt));
			newThread.start();
			currentDownloads.add(newThread);
			try {
				newThread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			blocksLeft--;
		}




//		while(getLowestAvailableBlockIndex()>0){
//			this.assignPeer();
//		}
//
//
//			Iterator it=this.peers.keySet().iterator();
//			for(int a=0;it.hasNext();a++){//for each peer
//				if(this.peers.keySet().){
//					new Thread(new BlockDownloadInstance(this.requestedFile, a, this.peersConnections.get(a), this.fileBuilt)).start();
//				}
//			}
//
		//wait all BlockDownloadInstance to end (join) and..

//		this.writeFile();
	}

	private void writeBlockToFile(byte[] block, int blockNumber){
		try {
			this.fileBuilt.write(block, blockNumber*TransferConsts.KILO_BYTE, TransferConsts.KILO_BYTE);
			this.fileBuilt.flush();
		} catch (IOException e) {
			e.printStackTrace(System.err);
		}
	}

	private void closeFile(){
		try {
			this.fileBuilt.flush();
			this.fileBuilt.close();
		} catch (IOException e) {
			e.printStackTrace(System.err);
		}
	}

}
